import random
import string
import uuid
import threading
from typing import Union, Optional


class RandomData:

    NickNames = ["米老鼠", "唐老鸭", "小熊维尼", "超级玛丽", "蓝精灵", "花仙子", "蝙蝠侠"]

    @staticmethod
    def random_str(length: int = 20, has_num: bool = False) -> str:
        """
        generate a random str and len == length
        :param length: the random str`length, default=20
        :param has_num: has int?
        :return: str
        """

        all_char = string.ascii_lowercase + string.ascii_uppercase
        if has_num:
            all_char += string.digits

        lis = list()
        for _ in range(length):
            lis.extend(random.choices(all_char, k=1))
        return ''.join(lis)

    @staticmethod
    def random_int(length: int = 4) -> str:
        """
        generate a random str(int) and len == length
        :param length: Specified length，default = 4
        :return: str
        """

        all_char = string.digits
        lis = list()
        for _ in range(length):
            lis.extend(random.choices(all_char, k=1))
        return ''.join(lis)

    @classmethod
    def random_username(cls, length: int = 6) -> str:
        """
        generate a random str and len == length
        :param length: the random str`length, default=6
        :return: str
        """

        name = cls.random_str(length=6, has_num=True)

        return f'soulmate_{name}'

    @classmethod
    def random_nickname(cls) -> str:
        """预定义的昵称"""

        # 随机选择一个
        return random.choice(cls.NickNames)


class UidGenerator:
    """<class 'common.tools.UidGenerator'>"""

    @staticmethod
    def u_id() -> str:
        return f'{uuid.uuid4().hex}'

    def __str__(self) -> str:
        return self.u_id()

    def __repr__(self) -> str:
        return self.u_id()


def singleton(cls):
    _instance = dict()

    def inner(*args, **kwargs):
        with threading.Lock():
            if cls not in _instance:
                _instance[cls] = cls(*args, **kwargs)
            return _instance[cls]

    return inner


class NumOp:

    @staticmethod
    def convert(f_v: Optional[float] = None, s_v: Optional[str] = None) -> float:
        """浮点数的数字或者浮点数字符串 转换为小数点后两位精度的浮点数"""

        if f_v:
            return float('%.2f' % f_v)
        elif s_v:
            return float('%.2f' % float(s_v))
        return 0.0
